/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.miit.elearning.servlets;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.hibernate.Session;
import ru.miit.elearning.hibernate.dao.HibernateUtil;
import ru.miit.elearning.hibernate.dto.Document;
import ru.miit.elearning.hibernate.dto.DocumentContent;
import ru.miit.elearning.hibernate.dto.DocumentContentId;

/**
 *
 * @author Cyclone
 */
public class FileDownloadServlet extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //response.setContentType("text/html;charset=UTF-8");
        // PrintWriter out = response.getWriter();
        OutputStream os = null;

        Session session = null;

        try {
            session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();

            int docId = Integer.parseInt(request.getParameter("docId"));
            String versionString = request.getParameter("version");
            Integer version = null;
            if (versionString != null && versionString.length() > 0) {
                version = Integer.parseInt(versionString);
                versionString = null;
            }

            DocumentContent dc = null;
            if (version == null) {
                Document doc = (Document) session.get(Document.class, docId);
                if (doc != null) {
                    dc = doc.getCurrentVersionContent();
                }
            } else {
                dc = (DocumentContent) session.get(DocumentContent.class, new DocumentContentId(docId, version));
            }
            if (dc != null) {
                /*
                FileOutputStream fos = null;
                byte[] contentBytes = dc.getContent();
                fos = new FileOutputStream("C:\\Cyclone\\_"+dc.getFileName());
                fos.write(contentBytes);
                fos.close();
                 */

                //String encodedName = URLEncoder.encode( dc.getFileName(), "UTF-8");
                //System.out.println("encodedName = " + encodedName);

                String fileName = dc.getFileName();

                //response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

                // WORKING FOR: FF3, IE8, CHROME4; NOT WORKING FOR: OPERA 10 :(
                String userAgent = request.getHeader("USER-AGENT").toLowerCase();
                fileName = URLEncoder.encode(fileName, "UTF8");
                if (userAgent != null
                        && (userAgent.contains("chrome")
                        || userAgent.contains("msie"))) {
                    response.setHeader(
                            "Content-Disposition",
                            "attachment; filename=\"" + fileName + "\"");
                } else {
                    response.setHeader(
                            "Content-Disposition",
                            "attachment; filename*=\"utf-8'" + fileName + "\"");
                }

                response.setContentType(dc.getMime());

                os = response.getOutputStream();

                ByteArrayInputStream bais = new ByteArrayInputStream(dc.getContent());
                byte[] buf = new byte[1024 * 4];
                int read = -1;
                while ((read = bais.read(buf)) >= 0) {
                    os.write(buf);
                }
                os.flush();
                //bais.read(b)


                //os.write(dc.getContent());
                //os.flush();


                /*

                /*
                int count = 0;
                while ((count = in.read(buf)) >= 0) {
                out.write(buf, 0, count);
                }
                 */
            }
            if (session != null && session.isOpen()) {
                session.getTransaction().commit();
            }
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
            if (os != null) {
                os.flush();
                os.close();
            }
            /*
            if (out != null) {
            out.close();
            }
             */
        }
    }

    public static void returnFile(String filename, Writer out)
            throws IOException {
        Reader in = null;
        try {
            in = new BufferedReader(new FileReader(filename));
            char[] buf = new char[4 * 1024];  // 4K char buffer
            int charsRead;
            while ((charsRead = in.read(buf)) != -1) {
                out.write(buf, 0, charsRead);
            }
        } finally {
            if (in != null) {
                in.close();
            }
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
